package com.zenithmind.user.pojo.domain.valueobject;

import lombok.Value;
import io.swagger.v3.oas.annotations.media.Schema;

/**
 * 租户配额值对象
 * 遵循单一职责原则：只负责租户配额管理
 * 遵循封装原则：不可变对象，业务逻辑封装
 */
@Value
@Schema(description = "租户配额")
public class TenantQuota {
    
    private static final int DEFAULT_MAX_USERS = 100;
    private static final long DEFAULT_STORAGE_QUOTA = 10L * 1024L * 1024L * 1024L; // 10GB
    private static final long UNLIMITED = -1L;

    @Schema(description = "最大用户数")
    int maxUsers;

    @Schema(description = "当前用户数")
    int currentUsers;

    @Schema(description = "存储配额（字节）")
    long storageQuota;

    @Schema(description = "已用存储（字节）")
    long storageUsed;

    /**
     * 创建默认配额
     */
    public static TenantQuota defaultQuota() {
        return new TenantQuota(DEFAULT_MAX_USERS, 0, DEFAULT_STORAGE_QUOTA, 0L);
    }

    /**
     * 创建无限制配额
     */
    public static TenantQuota unlimited() {
        return new TenantQuota(Integer.MAX_VALUE, 0, UNLIMITED, 0L);
    }

    /**
     * 创建自定义配额
     */
    public static TenantQuota create(int maxUsers, long storageQuota) {
        if (maxUsers <= 0) {
            throw new IllegalArgumentException("最大用户数必须大于0");
        }
        if (storageQuota < 0 && storageQuota != UNLIMITED) {
            throw new IllegalArgumentException("存储配额必须为正数或-1（无限制）");
        }
        return new TenantQuota(maxUsers, 0, storageQuota, 0L);
    }

    /**
     * 创建带使用量的配额
     */
    public static TenantQuota create(int maxUsers, int currentUsers, long storageQuota, long storageUsed) {
        if (maxUsers <= 0) {
            throw new IllegalArgumentException("最大用户数必须大于0");
        }
        if (currentUsers < 0) {
            throw new IllegalArgumentException("当前用户数不能为负数");
        }
        if (currentUsers > maxUsers) {
            throw new IllegalArgumentException("当前用户数不能超过最大用户数");
        }
        if (storageQuota < 0 && storageQuota != UNLIMITED) {
            throw new IllegalArgumentException("存储配额必须为正数或-1（无限制）");
        }
        if (storageUsed < 0) {
            throw new IllegalArgumentException("已用存储不能为负数");
        }
        if (storageQuota != UNLIMITED && storageUsed > storageQuota) {
            throw new IllegalArgumentException("已用存储不能超过存储配额");
        }
        return new TenantQuota(maxUsers, currentUsers, storageQuota, storageUsed);
    }

    /**
     * 增加用户
     */
    public TenantQuota addUser() {
        if (currentUsers >= maxUsers) {
            return null; // 返回null表示操作失败
        }
        return new TenantQuota(maxUsers, currentUsers + 1, storageQuota, storageUsed);
    }

    /**
     * 减少用户
     */
    public TenantQuota removeUser() {
        if (currentUsers <= 0) {
            return null; // 返回null表示操作失败
        }
        return new TenantQuota(maxUsers, currentUsers - 1, storageQuota, storageUsed);
    }

    /**
     * 更新存储使用量
     */
    public TenantQuota updateStorageUsed(long deltaSize) {
        long newUsed = storageUsed + deltaSize;
        
        if (newUsed < 0) {
            throw new IllegalArgumentException("存储使用量不能为负数");
        }
        
        if (storageQuota != UNLIMITED && newUsed > storageQuota) {
            return null; // 返回null表示操作失败
        }
        
        return new TenantQuota(maxUsers, currentUsers, storageQuota, newUsed);
    }

    /**
     * 设置新的用户配额
     */
    public TenantQuota withMaxUsers(int newMaxUsers) {
        if (newMaxUsers <= 0) {
            throw new IllegalArgumentException("最大用户数必须大于0");
        }
        if (currentUsers > newMaxUsers) {
            throw new IllegalArgumentException("新的最大用户数不能小于当前用户数");
        }
        return new TenantQuota(newMaxUsers, currentUsers, storageQuota, storageUsed);
    }

    /**
     * 设置新的存储配额
     */
    public TenantQuota withStorageQuota(long newStorageQuota) {
        if (newStorageQuota < 0 && newStorageQuota != UNLIMITED) {
            throw new IllegalArgumentException("存储配额必须为正数或-1（无限制）");
        }
        if (newStorageQuota != UNLIMITED && storageUsed > newStorageQuota) {
            throw new IllegalArgumentException("新的存储配额不能小于当前使用量");
        }
        return new TenantQuota(maxUsers, currentUsers, newStorageQuota, storageUsed);
    }

    /**
     * 检查是否可以添加用户
     */
    public boolean canAddUser() {
        return currentUsers < maxUsers;
    }

    /**
     * 检查是否可以使用指定大小的存储空间
     */
    public boolean canUseStorage(long size) {
        if (size < 0) {
            return false;
        }
        if (storageQuota == UNLIMITED) {
            return true;
        }
        return storageUsed + size <= storageQuota;
    }

    /**
     * 获取剩余用户数
     */
    public int getRemainingUsers() {
        return Math.max(0, maxUsers - currentUsers);
    }

    /**
     * 获取剩余存储空间
     */
    public long getRemainingStorage() {
        if (storageQuota == UNLIMITED) {
            return Long.MAX_VALUE;
        }
        return Math.max(0, storageQuota - storageUsed);
    }

    /**
     * 获取用户使用率（0-100）
     */
    public double getUserUsagePercentage() {
        if (maxUsers == 0) {
            return 0.0;
        }
        return (double) currentUsers / maxUsers * 100.0;
    }

    /**
     * 获取存储使用率（0-100）
     */
    public double getStorageUsagePercentage() {
        if (storageQuota == UNLIMITED || storageQuota == 0) {
            return 0.0;
        }
        return (double) storageUsed / storageQuota * 100.0;
    }

    /**
     * 检查用户是否已满
     */
    public boolean isUsersFull() {
        return currentUsers >= maxUsers;
    }

    /**
     * 检查存储是否已满
     */
    public boolean isStorageFull() {
        if (storageQuota == UNLIMITED) {
            return false;
        }
        return storageUsed >= storageQuota;
    }

    /**
     * 检查用户是否接近满（使用率超过90%）
     */
    public boolean isUsersNearFull() {
        return getUserUsagePercentage() > 90.0;
    }

    /**
     * 检查存储是否接近满（使用率超过90%）
     */
    public boolean isStorageNearFull() {
        return getStorageUsagePercentage() > 90.0;
    }

    /**
     * 检查存储是否无限制
     */
    public boolean isStorageUnlimited() {
        return storageQuota == UNLIMITED;
    }

    /**
     * 格式化显示存储配额
     */
    public String formatStorageQuota() {
        if (storageQuota == UNLIMITED) {
            return "无限制";
        }
        return formatBytes(storageQuota);
    }

    /**
     * 格式化显示已用存储
     */
    public String formatStorageUsed() {
        return formatBytes(storageUsed);
    }

    /**
     * 格式化显示配额信息
     */
    public String formatQuotaInfo() {
        return String.format("用户: %d/%d, 存储: %s/%s", 
                           currentUsers, maxUsers, 
                           formatStorageUsed(), formatStorageQuota());
    }

    /**
     * 格式化字节大小
     */
    private String formatBytes(long bytes) {
        if (bytes < 1024) {
            return bytes + " B";
        }
        int exp = (int) (Math.log(bytes) / Math.log(1024));
        String pre = "KMGTPE".charAt(exp - 1) + "";
        return String.format("%.1f %sB", bytes / Math.pow(1024, exp), pre);
    }
}
